﻿
using AB.ServiceDirectory.Commons.DataFilters;

namespace AB.ServiceDirectory.Dao
{
    using System;
    using System.Linq;
    using Commons;
    using Entities;

    /// <summary>
    /// HungContactDao Class
    /// </summary>
    public sealed class HungContactDao
    {
        /// <summary>
        /// Services Directory Data Context
        /// </summary>
        private static readonly ServicesDirectoryDataContext DbContext = DB.Context;

        /// <summary>
        /// Selects the contact by id.
        /// </summary>
        /// <returns>A contact </returns>
        public static Contact SelectContactById(int contactId)
        {
            Contact contact = DbContext.Contacts.FirstOrDefault(c => c.ContactId == contactId);
            return contact;
        }

        /// <summary>
        /// Selects all contact types.
        /// </summary>
        /// <returns></returns>
        public static IQueryable<ContactType> SelectAllContactTypes()
        {
            IQueryable<ContactType> data = DbContext.ContactTypes.Select(c => c);
            return data;
        }

        /// <summary>
        /// Selects all best method contact
        /// </summary>
        /// <returns></returns>
        public static IQueryable<BestContactMethod> SelectAllBestMethodContacts()
        {
            IQueryable<BestContactMethod> data = DbContext.BestContactMethods.Select(c => c);
            return data;
        }

        /// <summary>
        /// Gets the list.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <param name="sortType">Type of the sort.</param>
        /// <param name="startRowIndex">Start index of the row.</param>
        /// <param name="maxRows">The max rows.</param>
        /// <returns></returns>
        public static IQueryable<Contact> GetList(HContactFilter filter, string sortType, int startRowIndex, int maxRows)
        {
            IQueryable<Contact> query = from contact in DbContext.Contacts
                                        select contact;

            // 1. Filter method
            if (filter != null)
            {
                query = GetListFilter(query, filter);
            }

            // 2. Sorting column
            query = GetListSort(query, sortType);

            // 3. Paging
            query = query.Skip(startRowIndex).Take(maxRows);

            return query;
        }

        /// <summary>
        /// Gets the list filter.
        /// </summary>
        /// <param name="query">The query.</param>
        /// <param name="filter">The filter.</param>
        /// <returns></returns>
        private static IQueryable<Contact> GetListFilter(IQueryable<Contact> query, HContactFilter filter)
        {
            if (!string.IsNullOrEmpty(filter.FirstName))
            {
                query = query.Where(c => c.FirstName.StartsWith(filter.FirstName));
            }

            if (!string.IsNullOrEmpty(filter.Surname))
            {
                query = query.Where(c => c.Surname.StartsWith(filter.Surname));
            }

            if (!filter.IncludeInactiveContact)
            {
                query = query.Where(c => c.IsActive);
            }
            return query;
        }

        /// <summary>
        /// Gets the list sort.
        /// </summary>
        /// <param name="query">The query.</param>
        /// <param name="sortType">Type of the sort.</param>
        /// <returns></returns>
        private static IQueryable<Contact> GetListSort(IQueryable<Contact> query, string sortType)
        {
            bool desc = false;
            if (!string.IsNullOrEmpty(sortType))
            {
                string[] values = sortType.Split(' ');
                sortType = values[0];

                if (values.Length > 1)
                {
                    desc = (values[1] == "DESC");
                }

                switch (sortType)
                {
                    case "ContactName":
                        query = desc
                                    ? query.OrderByDescending(c => c.FirstName).ThenBy(c => c.Surname)
                                    : query.OrderBy(c => c.FirstName).ThenBy(c => c.Surname);
                        break;

                    case "MobilePhone":
                        query = desc ? query.OrderByDescending(c => c.MobilePhone) : query.OrderBy(c => c.MobilePhone);
                        break;

                    case "Email":
                        query = desc ? query.OrderByDescending(c => c.Email) : query.OrderBy(c => c.Email);
                        break;

                    case "ContactTypeName":
                        query = desc
                                    ? query.OrderByDescending(c => c.ContactType.ContactTypeName)
                                    : query.OrderBy(c => c.ContactType.ContactTypeName);
                        break;

                    case "IsActive":
                        query = desc ? query.OrderByDescending(c => c.IsActive) : query.OrderBy(c => c.IsActive);
                        break;

                    default:
                        query = desc ? query.OrderByDescending(c => c.ContactId) : query.OrderBy(c => c.ContactId);
                        break;
                }
            }
            return query;
        }

        /// <summary>
        /// Gets the list count.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <returns></returns>
        public static int GetListCount(HContactFilter filter)
        {
            IQueryable<Contact> query = from contact in DbContext.Contacts
                                        select contact;
            if (filter != null)
            {
                return GetListFilter(query, filter).Count();
            }
            return query.Count();
        }

        /// <summary>
        /// Inserts the contact.
        /// </summary>
        /// <param name="contact">The contact.</param>
        /// <returns></returns>
        public bool InsertContact(Contact contact)
        {
            if (contact.FirstName==null)
            {
                return false;
            }

            if (contact.Surname==null)
            {
                return false;
            }

            if (contact.ContactType==null)
            {
                return false;
            }
            try
            {
                DbContext.Contacts.InsertOnSubmit(contact);
                DbContext.SubmitChanges();
                return true;
            }
            catch (NullReferenceException e)
            {
                Log.GetLog(this).Error(e);
                return false;
            }
        }

        /// <summary>
        /// Updates the contact.
        /// </summary>
        /// <param name="contact">The contact.</param>
        /// <returns></returns>
        public bool UpdateContact(Contact contact)
        {
            ContactType contactType =
                DB.Context.ContactTypes.FirstOrDefault(ct => ct.ContactTypeId == contact.ContactTypeId);

            BestContactMethod bestContactMethod = DB.Context.BestContactMethods.FirstOrDefault(
                ct => ct.BestContactMethodId == contact.BestContactMethodId);

            if(contact.ContactType==null)
            {
                return false;
            }

            if (contact.Surname==null)
            {
                return false;
            }

            if (contact.FirstName==null)
            {
                return false;
            }
            try
            {
                Contact contacts = DbContext.Contacts.FirstOrDefault(c => c.ContactId == contact.ContactId);
                if (contacts != null)
                {
                    contacts.FirstName = contact.FirstName;
                    contacts.Surname = contact.Surname;
                    contacts.KnownAs = contact.KnownAs;
                    contacts.OfficePhone = contact.OfficePhone;
                    contacts.MobilePhone = contact.MobilePhone;
                    contacts.Email = contact.Email;
                    contacts.ManageId = contact.ManageId;
                    contacts.ContactType = contactType;
                    contacts.BestContactMethod = bestContactMethod;
                    contacts.JobRole = contact.JobRole;
                    contacts.IsActive = contact.IsActive;
                    DbContext.SubmitChanges();
                    return true;
                }
            }
            catch (NullReferenceException e)
            {
                Log.GetLog(this).Error(e);
                return false;
            }
            return false;
        }
    }
}